<Query Kind="Statements">
  <NuGetReference>Microsoft.Extensions.ObjectPool</NuGetReference>
  <NuGetReference>SharpSvn</NuGetReference>
  <Namespace>SharpSvn</Namespace>
  <Namespace>System.Net</Namespace>
  <Namespace>System.Threading.Tasks</Namespace>
  <Namespace>Microsoft.Extensions.ObjectPool</Namespace>
</Query>

// 2025年7月30日：
// 由于使用SVN时存在一些耗时操作，比如对比当前 FolderNode 是否同步
// 因此尝试使用 Parallel 来优化这些操作

// Result: 没有成功
// 任务类型是 I/O 密集型，而非 CPU 密集型，因此实际上大部分事件在等待网络数据
// 使用 Parallel.ForEach 反而增加了上下文切换

using SvnClient _client = new SvnClient();
NetworkCredential _credential = new NetworkCredential("Administrator", "sicont_server");
_client.Authentication.Clear();
_client.Authentication.DefaultCredentials = _credential;
_client.Authentication.SslServerTrustHandlers += (sender, e) =>
{
    e.AcceptedFailures = e.Failures;
    e.Save = true;
};

string _remote_repository = "https://Vc2000/svn/ProjectRepository/";
string _local_repository = "D:\\WorkSpace";

SvnPathTarget _local_target = new(_local_repository);
SvnUriTarget _remote_target = new(_remote_repository);

/**************************************************************************************/
#if true
// 使用 GetList 获取所有的 FileName
Stopwatch _sw_01 = Stopwatch.StartNew();
SvnListArgs _list_args = new() { Depth = SvnDepth.Infinity };
_client.GetList(_remote_target, _list_args, out var _list_collection);
_list_collection.Count.Dump();
$"GetList 耗时：{_sw_01.ElapsedMilliseconds} ms".Dump();
// *****************************************************
// Result: 70000 个文件大约耗时 7 秒
// *****************************************************
#endif

#if false
// 使用 GetInfo SvnDepth.Infinity 获取远程的信息
Stopwatch _sw_02 = Stopwatch.StartNew();
SvnInfoArgs _info_args = new() { Depth = SvnDepth.Infinity, ThrowOnError = false };
_client.GetInfo(_remote_target, _info_args, out var _local_info_list);
_local_info_list.Count.Dump();
$"GetInfo 耗时：{_sw_02.ElapsedMilliseconds} ms".Dump();
// *****************************************************
// Result: 70000 个文件大约耗时 28 秒
// *****************************************************
#endif

#if false
// 改用 GetInfo Depth = SvnDepth.Empty 获取远程在本地的信息
Stopwatch _sw_03 = Stopwatch.StartNew();
SvnInfoArgs _info_args_03 = new() { Depth = SvnDepth.Empty, ThrowOnError = false };
foreach (var _item in _list_collection)
{
    string _path = Path.Combine(_local_repository, _item.Path);
    _client.GetInfo(_path, _info_args_03, out var _local_info_list_03);
}
_list_collection.Count.Dump();
$"GetInfo 耗时：{_sw_03.ElapsedMilliseconds} ms".Dump();
// *****************************************************
// Result: 70000 个文件大约耗时 40 秒
// *****************************************************
#endif

// 使用 Parallel.ForEach 优化上面的逻辑
// SvnClient 并非线程安全的，因此无法共享，为每个线程创建自己的 SvnClient
Stopwatch _sw_04 = Stopwatch.StartNew();
SvnInfoArgs _info_args_04 = new() { Depth = SvnDepth.Empty, ThrowOnError = false };
var parallelOptions = new ParallelOptions
{
    MaxDegreeOfParallelism = 2
};

Parallel.ForEach(_list_collection, parallelOptions, _item => 
{
    SvnClient _client_temp = new SvnClient();
    NetworkCredential _credential = new NetworkCredential("Administrator", "sicont_server");
    _client_temp.Authentication.Clear();
    _client_temp.Authentication.DefaultCredentials = _credential;
    _client_temp.Authentication.SslServerTrustHandlers += (sender, e) =>
    {
        e.AcceptedFailures = e.Failures;
        e.Save = true;
    };

    string _path = Path.Combine(_local_repository, _item.Path);
    if (_client_temp is null)
    {
        "Client is null".Dump();
        return;
    }
    
    _client_temp.GetInfo(_path, _info_args_04, out var _local_info_list_04);
});
_list_collection.Count.Dump();
$"GetInfo 耗时：{_sw_04.ElapsedMilliseconds} ms".Dump();
